<template>
    <a-spin :tip="$t('loadingText')" :spinning="spinning">
        <a-layout :style="{
            height: mainStore().containerHeight - mainStore().headHeight + 'px',
        }">
            <a-layout-header style="height: 60px;">
                <a-form :model="pageRequest" layout="inline" style="margin-left:20px">
                    <a-form-item :label="$t('upperComputer.user.userAccount')">
                        <a-input v-model:value="pageRequest.account" :maxlength="50" size="small" allow-clear />
                    </a-form-item>
                    <a-form-item :label="$t('upperComputer.user.userName')">
                        <a-input v-model:value="pageRequest.displayName" :maxlength="50" size="small" allow-clear />
                    </a-form-item>
                    <a-form-item>
                        <a-button type="primary" @click="requestSearch" size="small">
                            {{ $t("common.search") }}
                        </a-button>
                    </a-form-item>
                </a-form>
                <menu-button :baseMenuButton="baseMenuButton" @callFunc="callFunc" />
            </a-layout-header>
            <a-layout-content>
                <a-table rowKey="id" :scroll="{
                    x: 750 /** x是columns的sum(width)值，且不能小于sum */,
                    y:
                        mainStore().containerHeight -
                        mainStore().headHeight -
                        mainStore().footHeight -
                        115
                }" :pagination="false" :data-source="pageResult.items" :rowSelection="rowSelection">
                    <a-table-column data-index="index" :width="100" :title="$t('common.serialNumber')">
                        <template #default="item">
                            <span>
                                {{
                                    item.index +
                                    1 /** 详细说明看columns的slots，在下边。index跟自己定义的要一致。item代表着行数据集合。 */
                                }}
                            </span>
                        </template>
                    </a-table-column>
                    <a-table-column data-index="account" :width="160" :title="$t('upperComputer.user.userAccount')"
                        ellipsis />
                    <a-table-column data-index="displayName" :width="160" :title="$t('upperComputer.user.userName')"
                        ellipsis />
                    <a-table-column data-index="sex" :width="100" :title="$t('upperComputer.user.sex')" align="center"
                        ellipsis>
                        <template #default="item">
                            <a-tag :color="getSex(item, 0)">{{ getSex(item, 1) }}</a-tag>
                        </template>
                    </a-table-column>
                    <a-table-column data-index="isActive" :width="100" :title="$t('upperComputer.user.accountState')"
                        align="center" ellipsis>
                        <template #default="item">
                            <a-tag :color="getIsActive(item, 0)">{{
                                getIsActive(item, 1)
                            }}</a-tag>
                        </template>
                    </a-table-column>
                    <a-table-column data-index="creationTime" :width="200" :title="$t('upperComputer.user.creationTime')"
                        align="center" ellipsis />
                    <a-table-column data-index="description" :title="$t('upperComputer.user.description')" ellipsis />
                    <template #expandedRowRender="item">
                        <a-table rowKey="id" :data-source="item.record.baseRoleUser" :pagination="false">
                            <a-table-column data-index="roleCode" :width="160" :title="$t('upperComputer.user.roleCode')"
                                ellipsis />
                            <a-table-column data-index="roleName" :width="160" :title="$t('upperComputer.user.roleName')"
                                ellipsis />
                        </a-table>
                    </template>
                </a-table>
            </a-layout-content>
            <a-layout-footer :style="{ height: mainStore().footHeight + 'px' }">
                <pagination :pageRequest="pageRequest" :pageResult="pageResult" @callFunc="callFunc('search')" />
            </a-layout-footer>
        </a-layout>
    </a-spin>

    <a-modal :title="$t('menuButton.' + (currentRow ? 'put' : 'post'))" centered :visible="addOrEditVisible"
        :confirm-loading="spinning" :maskClosable="false" @ok="addOrEditOk" @cancel="addOrEditVisible = false"
        width="600px">
        <add-or-edit v-if="addOrEditVisible" ref="addOrEditRef" :id="id" />
    </a-modal>
</template>

<script setup lang='ts'>
import i18n from '@/i18n';
import cache from '@/utils/cache';
import MenuButton from '@/components/menu-button/index.vue';
import Pagination from '@/components/pagination/index.vue';
import AddOrEdit from './add-or-edit.vue';
import { PagedResultDto } from '@/models/paged-result';
import { mainStore } from '@/store/main';
import { message } from 'ant-design-vue';
import { computed, onMounted, reactive, ref, unref, type Ref } from 'vue';
import { confirm } from '@/utils';
import { UserResultRequestDto, type UserResultDto } from '@/models/user';
import type { MenuButtonResultDto } from '@/models/menu-button';
import { deleteUserApi, getUsersApi, putDisableApi, putEnableApi, putRecoverApi } from '@/services/user';

defineProps<{ baseMenuButton: Array<MenuButtonResultDto> }>();

const admin: string = 'Admin';
const spinning: Ref<boolean> = ref<boolean>(false);
const pageRequest: UserResultRequestDto = reactive<UserResultRequestDto>(new UserResultRequestDto);
const pageResult: Ref<PagedResultDto<UserResultDto>> = ref<PagedResultDto<UserResultDto>>(new PagedResultDto<UserResultDto>);
const currentRow: Ref<UserResultDto | null> = ref<UserResultDto | null>(null);
const selectedRowKeys: Ref<Array<string>> = ref<Array<string>>(new Array<string>);
const rowSelection = computed(() => {
    return {
        type: 'radio',
        selectedRowKeys: unref<Array<string>>(selectedRowKeys),
        onChange: (changableRowKeys: Array<string>, selectedRows: Array<UserResultDto>) => {
            currentRow.value = selectedRows[0];
            selectedRowKeys.value = changableRowKeys;
        }
    }
});

const id: Ref<number> = ref<number>(0);
const addOrEditVisible: Ref<boolean> = ref<boolean>(false);
const addOrEditRef = ref();

onMounted(async () => {
    await search();
})

/**
 * 获取数据
 */
async function search(): Promise<void> {
    pageRequest.skipCount =
        (pageRequest.current - 1) * pageRequest.maxResultCount;
    spinning.value = true;
    pageResult.value = await getUsersApi(pageRequest);
    spinning.value = false;
    currentRow.value = null;
    selectedRowKeys.value = new Array<string>;
}

async function requestSearch(): Promise<void> {
    pageRequest.current = 1;
    await search();
}

/**
 * 判断sex:item是数据集合，type是类型。0代表着tag的type，1代表着要返回的中英文
 * @param item 
 * @param type 
 */
function getSex(item: any, type: number): string {
    const value: number = item.record.sex;
    if (!type) {
        return value === 0 ? 'default' : value === 1 ? 'success' : 'warning';
    }
    return i18n.global.t('upperComputer.user.sex' + value);
}

/**
 * 判断isActive:item是数据集合，type是类型。0代表着tag的type，1代表着要返回的中英文
 */
function getIsActive(item: any, type: number): string {
    const value: boolean = item.record.isActive;
    if (!type) {
        return value ? 'success' : 'default';
    }
    return value ? i18n.global.t('upperComputer.user.enable') : i18n.global.t('upperComputer.user.disable');
}

function callFunc(funcName: string): void {
    eval(funcName + '()');
}

function post(): void {
    id.value = 0;
    addOrEditVisible.value = true;
}

function put(): void {
    if (!currentRow.value) {
        message.warning(i18n.global.t('common.editOne'));
        return;
    }
    if (
        currentRow.value.account === admin &&
        currentRow.value.id !== cache.getUserInfo()?.id
    ) {
        message.warning(i18n.global.t('upperComputer.user.required.noEditSA'));
        return;
    }
    id.value = currentRow.value.id;
    addOrEditVisible.value = true;
}

/**
 * 重置密码
 */
async function recover(): Promise<void> {
    if (!currentRow.value) {
        message.warning(i18n.global.t('upperComputer.user.required.resetPassword'));
        return;
    }
    if (currentRow.value.account === admin) {
        message.warning(i18n.global.t('upperComputer.user.required.noResetSAPassword'));
        return;
    }
    if (await confirm(i18n.global.t('common.prompt').toString(), i18n.global.t('upperComputer.user.required.determine').toString())) {
        await putRecoverApi({ id: currentRow.value.id });
        message.info(i18n.global.t('upperComputer.user.required.resetSuccess'));
        search();
    }
}

/**
 * 启用
 */
async function enable(): Promise<void> {
    if (!currentRow.value) {
        message.warning(i18n.global.t('common.enableOne'));
        return;
    }
    if (currentRow.value.account === admin) {
        message.warning(i18n.global.t('upperComputer.user.required.noEnableSA'));
        return;
    }
    if (currentRow.value.isActive) {
        message.warning(i18n.global.t('upperComputer.user.required.isEnable'));
        return;
    }
    if (await confirm(i18n.global.t('common.prompt').toString(), i18n.global.t('common.enableIt').toString())) {
        await putEnableApi({ id: currentRow.value.id });
        message.info(i18n.global.t('common.enableSuccess'));
        search();
    }
}

/**
 * 禁用
 */
async function disable(): Promise<void> {
    if (!currentRow.value) {
        message.warning(i18n.global.t('common.disableOne'));
        return;
    }
    if (currentRow.value.account === admin) {
        message.warning(i18n.global.t('upperComputer.user.required.noDisableSA'));
        return;
    }
    if (currentRow.value.isActive) {
        message.warning(i18n.global.t('upperComputer.user.required.isDisable'));
        return;
    }
    if (await confirm(i18n.global.t('common.prompt').toString(), i18n.global.t('common.disableIt').toString())) {
        await putDisableApi({ id: currentRow.value.id });
        message.info(i18n.global.t("common.disableSuccess"));
        search();
    }
}

/**
 * 删除
 */
async function remove(): Promise<void> {
    if (!currentRow.value) {
        message.warning(i18n.global.t('common.deleteOne'));
        return;
    }

    if (currentRow.value.account === admin) {
        message.warning(i18n.global.t('upperComputer.user.required.noDeleteSA'));
        return;
    }
    if (await confirm(i18n.global.t('common.prompt').toString(), i18n.global.t('common.deleteIt').toString())) {
        await deleteUserApi(currentRow.value.id);
        message.success(i18n.global.t('common.deleteSuccess'));
        search();
    }
}

async function addOrEditOk(): Promise<void> {
    spinning.value = true;
    const isOk: boolean = await addOrEditRef.value.ok();
    if (isOk) {
        addOrEditVisible.value = false;
        await search();
    }
    spinning.value = false;
}
</script>